/*
 * ScheduleCreationWindowController.java
 * 
 * Copyright (c) 2008, Marshall Scorcio, Ralph Holzmann, 
 *                     Stewart Sweet, Tyler Hoersch, Jeffery Van Handel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of Wisconsin Oshkosh nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
  
import java.util.*;

public class ScheduleCreationWindowController implements ViewEventListener
{
    private ScheduleCreationWindow scheduleCreationWindow;
    private Vector<Employee> employees;
    private Schedule schedule;
    
    public ScheduleCreationWindowController()
    {
        scheduleCreationWindow = new ScheduleCreationWindow();
        scheduleCreationWindow.addViewEventListener(this);
        scheduleCreationWindow.setVisible(true);
    }
    
    public void setEmployees(Vector<Employee> employees)
    {
        this.employees = employees;
    }
    
    public void setSchedule(Schedule schedule)
    {
        this.schedule = schedule;
        String days[] = new String[7];
        for (int i = 0; i < 7; i++)
        {
            days[i] = Day.getNameFromDayOfWeek(schedule.getScheduledDayByIndex(i).getDayOfWeek());    
        }
        scheduleCreationWindow.setDays(days);
        scheduleCreationWindow.setDateRange(schedule.toString());
    }
    
    public void viewEventOccurred(ViewEvent event)
    {
        if (event.toString().equals("DaySelectionChanged"))
        {
            selectDay();
        }
        else if (event.toString().equals("ShiftSelectionChanged"))
        {
            selectShift();
        }
        else if (event.toString().equals("Apply"))
        {
            applyChanges();
        }
        else if (event.toString().equals("ViewSchedule"))
        {
            viewSchedule();
        }
        else if (event.toString().equals("Cancel"))
        {
            cancelChanges();
        }
        else if (event.toString().equals("RemoveShift"))
        {
            removeShift();
        }
        else if (event.toString().equals("AddShift"))
        {
            String[] shifts = ((ShiftDialog) event.getSource()).toStringArray();
            addShift(shifts);
        }
        else if (event.toString().equals("ShowAllEmployeesToggled"))
        {
            toggleViewAllEmployees();
        }
        else if (event.toString().equals("DeleteEmployeeFromShift"))
        {
            deleteEmployeeFromShift();
        }
        else if (event.toString().equals("AddEmployeeToShift"))
        {
            addEmployeeToShift();
        }
    }

    private void selectDay()
    {
        
        String selectedDay = scheduleCreationWindow.getSelectedDay();
        
        ScheduledDay day = schedule.getScheduledDayByDayOfWeek(Day.getDayOfWeekFromName(selectedDay));
        
        if (day.getNumberOfShifts() > 0)
        {
            String[] shiftNames = new String[day.getNumberOfShifts()];
            
            for (int i = 0; i < shiftNames.length; i++)
            {
                shiftNames[i] = day.getShiftAt(i).timeToString();
            }

            scheduleCreationWindow.setShifts(shiftNames);
        }
        else
        {
            scheduleCreationWindow.clearShifts();
        }
        
        selectShift();
    }
    
    private void selectShift()
    {
        String selectedShift = scheduleCreationWindow.getSelectedShift();  
        String selectedDay = scheduleCreationWindow.getSelectedDay();
        
        if (selectedShift != null)
        {
            ScheduledDay scheduledDay = schedule.getScheduledDayByDayOfWeek(Day.getDayOfWeekFromName(selectedDay));
            Shift shift = scheduledDay.findShiftByTime(new TimeBlock(selectedShift));
            
            String[] scheduledEmployeeNames = new String[0];
            
            if (shift.getNumberOfEmployees() > 0)
            {
                Vector<Employee> scheduledEmployees = shift.getEmployees();
                scheduledEmployeeNames = new String[shift.getNumberOfEmployees()];
                
                for (int i = 0; i < scheduledEmployeeNames.length; i++)
                {
                    scheduledEmployeeNames[i] = scheduledEmployees.elementAt(i).getName() + " [Scheduled]";
                }
            }
                
            String[] unscheduledEmployees = new String[0];  
            
            if (scheduleCreationWindow.isShowAllEmployeesChecked())
            {
                unscheduledEmployees = new String[employees.size()];
                
                for(int i = 0; i < employees.size(); i++)
                {
                    unscheduledEmployees[i] = employees.elementAt(i).getName();
                }
            }
            else
            {
                Vector<String> availableEmployees = new Vector<String>();
                
                for(int i = 0; i < employees.size(); i++)
                {
                    Day day = new Day(scheduledDay.getDayOfWeek(), scheduledDay.getDayOfMonth(), scheduledDay.getMonth(), scheduledDay.getYear());
                   
                    if (employees.elementAt(i).getAvailability().isAvailableForShift(day, shift))
                    {
                        availableEmployees.add(employees.elementAt(i).getName());
                    }
                }
                
                unscheduledEmployees = new String[availableEmployees.size()];
                
                for (int i = 0; i < unscheduledEmployees.length; i++)
                {
                    unscheduledEmployees[i] = availableEmployees.elementAt(i);
                }
            }
            
            String[] employeeNames = new String[scheduledEmployeeNames.length + unscheduledEmployees.length + 3];
         
            employeeNames[0] = "--- Scheduled Employees ---";
            System.arraycopy(scheduledEmployeeNames, 0, employeeNames, 1, scheduledEmployeeNames.length);

            employeeNames[scheduledEmployeeNames.length + 1] = " ";
            employeeNames[scheduledEmployeeNames.length + 2] = "--- Available Employees ---";
            System.arraycopy(unscheduledEmployees, 0, employeeNames, scheduledEmployeeNames.length + 3, unscheduledEmployees.length);

            scheduleCreationWindow.setEmployees(employeeNames);
        }
        else 
        {
            scheduleCreationWindow.clearEmployees();
        }
    }
       
    private void applyChanges()
    {
        ScheduleSerializer.saveSchedule(schedule);
    }
    
    private void viewSchedule()
    {
        ScheduleViewerWindow selectedSchedule = new ScheduleViewerWindow(schedule.toString(), schedule.getFullSchedule(employees));
        selectedSchedule.setVisible(true);   
    }
    
    private void cancelChanges()
    {
        scheduleCreationWindow.setVisible(false);
    }
    
    private void removeShift()
    {
        String selectedDay = scheduleCreationWindow.getSelectedDay();
        String selectedShift = scheduleCreationWindow.getSelectedShift();
        
        ScheduledDay day = schedule.getScheduledDayByDayOfWeek(Day.getDayOfWeekFromName(selectedDay));
        
        Shift shift = day.findShiftByTime(new TimeBlock(selectedShift));
        
        if (shift != null)
        {
            day.removeShift(shift);
        }
        
        selectDay();
    }
    
    private void addShift(String[] shifts)
    {
        for (int i = 0; i < shifts.length; i++)
        {
            scheduleCreationWindow.addShift(shifts[i]);
            schedule.addScheduledShiftAt(new Shift(shifts[i]), Day.getDayOfWeekFromName(scheduleCreationWindow.getSelectedDay()));
        }
    }
    
    private void toggleViewAllEmployees()
    {
        selectShift();
    }
    
    private void addEmployeeToShift()
    {
        String[] selectedEmployees = scheduleCreationWindow.getSelectedEmployees();
        String selectedDay = scheduleCreationWindow.getSelectedDay();
        String selectedShift = scheduleCreationWindow.getSelectedShift();
        
        ScheduledDay day = schedule.getScheduledDayByDayOfWeek(Day.getDayOfWeekFromName(selectedDay));
        
        Shift shift = day.findShiftByTime(new TimeBlock(selectedShift));
        
        if (shift != null)
        {
            for (int i = 0; i < selectedEmployees.length; i++)
            {
                Employee employee = null;
                
                for (int j = 0; j < employees.size(); j++)
                {
                    if (employees.elementAt(j).getName().equals(selectedEmployees[i]))
                    {
                        employee = employees.elementAt(j);
                    }
                }
                
                if (employee != null)
                {
                    shift.addEmployee(employee);
                }
            }
            selectShift();
        }
    }
    
    private void deleteEmployeeFromShift()
    {
        String[] selectedEmployees = scheduleCreationWindow.getSelectedEmployees();
        String selectedDay = scheduleCreationWindow.getSelectedDay();
        String selectedShift = scheduleCreationWindow.getSelectedShift();
        
        ScheduledDay day = schedule.getScheduledDayByDayOfWeek(Day.getDayOfWeekFromName(selectedDay));
        
        Shift shift = day.findShiftByTime(new TimeBlock(selectedShift));
        
        if (shift != null)
        {
            for (int i = 0; i < selectedEmployees.length; i++)
            {
                Employee employee = null;
                
                for (int j = 0; j < employees.size(); j++)
                {
                    if (selectedEmployees[i].indexOf(" [Scheduled") != -1)
                    {
                        if (employees.elementAt(j).getName().equals(selectedEmployees[i].substring(0, selectedEmployees[i].indexOf(" [Scheduled"))))
                        {
                            employee = employees.elementAt(j);
                        }
                    }
                }
                
                if (employee != null)
                {
                    shift.removeEmployee(employee);
                }
            }
            selectShift();
        }
    }
}

